package com.zby.simulationHibernate.util.reflect;

import com.zby.simulationHibernate.query.ResultTransformer;
import com.zby.simulationHibernate.util.common.CommonUtil;
import com.zby.simulationHibernate.util.exception.GenericException;
import com.zby.simulationHibernate.util.reflect.property.PropertyAccessor;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created By zby on 17:42 2019/1/23
 * 获取对象集合
 */

public class PersistentObject<T> {

    /**
     * 类字面常量，这样比较安全，也比较方便
     */
    private Class<T> persistenceClass;


    private ResultSet resultSet;

    public PersistentObject() {
    }

    public PersistentObject(Class<T> persistenceClass) {
        this.persistenceClass = persistenceClass;
    }

    public PersistentObject(ResultSet resultSet) {
        this.resultSet = resultSet;
    }

    public PersistentObject(Class<T> persistenceClass, ResultSet resultSet) {
        this.persistenceClass = persistenceClass;
        this.resultSet = resultSet;
    }

    /**
     * Created By zby on 17:46 2019/1/23
     * 获取属性名称
     */
    public List<T> getPersist() {
        if (CommonUtil.isNull(persistenceClass))
            throw new GenericException("找不到这个类clazz = " + persistenceClass.getName());
        if (CommonUtil.isNull(resultSet))
            throw new GenericException("结果集为result = " + resultSet);
        List<T> list = new ArrayList<>();
        try {
            while (resultSet.next()) {
                Field[] fields = persistenceClass.getDeclaredFields();
                T obj = persistenceClass.newInstance();
                for (Field field : fields) {
                    String fieldName = field.getName();
                    String columnName = PropertyUtil.propertyNameTransformColumnName(fieldName, true);
                    new PropertyAccessor<T>().setPropertyValue(obj, fieldName, resultSet, columnName);
                }
                list.add(obj);
            }
            return list;
        } catch (InstantiationException e) {
            System.out.println("实例化异常persistenceClass=" + persistenceClass);
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            System.out.println("非法访问异常persistenceClass=" + persistenceClass);
            e.printStackTrace();
        } catch (SQLException e) {
            System.out.println("结果集已经关闭resultSet=" + resultSet);
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Created By zby on 17:46 2019/1/23
     * 获取属性名称
     */
    public List<T> getPersist(ResultTransformer transformer) {
        if (CommonUtil.isNull(transformer))
            throw new GenericException("找不到这个类transformer = " + transformer);
        if (CommonUtil.isNull(resultSet))
            throw new GenericException("结果集为result = " + resultSet);
        List<T> list = new ArrayList<>();
        Class<T> clazz = transformer.getTarget();
        try {
            while (resultSet.next()) {
                Map<String, String> tupleMap = transformer.getTupleMap();
                if (CommonUtil.isNull(tupleMap)) {
                    throw new GenericException("不能没有属性的集合");
                }
                T obj = clazz.newInstance();
                for (Map.Entry<String, String> entry : tupleMap.entrySet()) {
                    String fieldName = entry.getKey();
                    String columnName = PropertyUtil.propertyNameTransformColumnName(fieldName, false);
                    new PropertyAccessor<T>().setPropertyValue(obj, fieldName, resultSet, columnName);
                }
                list.add(obj);
            }
            return list;
        } catch (InstantiationException e) {
            System.out.println("实例化异常persistenceClass=" + persistenceClass);
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            System.out.println("非法访问异常persistenceClass=" + persistenceClass);
            e.printStackTrace();
        } catch (SQLException e) {
            System.out.println("结果集已经关闭resultSet=" + resultSet);
            e.printStackTrace();
        }
        return null;
    }
}
